package top.yanxiaozhao.data.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import top.yanxiaozhao.data.common.GlobalResult;
import top.yanxiaozhao.data.common.WechatUtil;
import top.yanxiaozhao.data.domain.User;
import top.yanxiaozhao.data.service.UserService;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.UUID;

@Controller
public class LoginController {
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/api/login")
    @ResponseBody
    public GlobalResult login(@RequestParam(value = "code", required = false) String code,
                              @RequestParam(value = "rawData", required = false) String rawData,
                              @RequestParam(value = "signature", required = false) String signature,
                              @RequestParam(value = "encryptedData", required = false) String encryptedData,
                              @RequestParam(value = "iv", required = false) String iv) {
        // 接收用户信息
        JSONObject rawDataJson = JSON.parseObject(rawData);
        // 1.接收小程序发送的 code
        // 2.开发者服务器 登录凭证校验接口 appid + appsecret + code
        JSONObject SessionKeyOpenId = WechatUtil.getSessionKeyOrOpenId(code);
        // 3.接收微信接口服务 获取返回的参数
        String openid = SessionKeyOpenId.getString("openid");
        String sessionKey = SessionKeyOpenId.getString("session_key");

        // 4.校验签名 小程序发送的签名 signature 与服务器端生成的签名 signature2 = sha1(rawData + sessionKey)
        String signature2 = DigestUtils.sha1Hex(rawData + sessionKey);
        if (!signature.equals(signature2)) {
            return new GlobalResult(500, "签名校验失败", null);
        }

        // 5.根据返回的 User 实体类，判断用户是否是新用户，是的话，将用户信息存到数据库；不是的话，更新最新登录时间
        User user = userService.selectByOpenid(openid);
        // 这里不使用uuid了，使用对称加密对openid和session_key加密，将密文返回给小程序，登录校验就是对这个密文解密
        String skey = UUID.randomUUID().toString();
        if (user == null) {
            // 用户信息入库
            String nickname = rawDataJson.getString("nickname");
            String avatarUrl = rawDataJson.getString("avatarUrl");
            String gender = rawDataJson.getString("gender");
            user = new User(openid, skey, nickname, Integer.parseInt(gender), avatarUrl);
            userService.insert(user);
        } else {
            // TODO 更新用户的skey和登录时间
        }
        // 6.把结果返回给小程序
        GlobalResult result = new GlobalResult(200, "登录成功", skey);
        return result;
    }
}